/*
 * @Description  : 导出到命令行的一些指令的定义
 * @Version      : 0.1
 * @Company      : V-Think Development Team
 * @Author       : KiraVerSace@yeah.net
 * @Date         : 2021-01-07 10:26:25
 * @LastEditTime : 2022-04-09 04:26:50
 */
#include <xCommon.h>

/*导出指令 python3 shellTools.py  ../../../src */

static void hardfaultTest(void)
{
	/* Unalign fault */
	volatile int * SCB_CCR = (volatile int *) 0xE000ED14; // SCB->CCR
    volatile int * p;
    volatile int value;

    *SCB_CCR |= (1 << 3); /* bit3: UNALIGN_TRP. */

    p = (int *) 0x00;
    value = *p;

    p = (int *) 0x04;
    value = *p;

    p = (int *) 0x03;
    value = *p;

	/* Div 0 fault */
    volatile int * SCB_CCR1 = (volatile int *) 0xE000ED14; // SCB->CCR
    int x, y, z;

    *SCB_CCR1 |= (1 << 4); /* bit4: DIV_0_TRP. */

    x = 10;
    y = 0;
    z = x / y;
}
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
hardFault, hardfaultTest, Let the MCU enter hardfault mode);

static void systemSoftReboot(void)
{
	vTaskDelay(1500);

	__disable_irq();
	NVIC_SystemReset();
}
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
reboot, systemSoftReboot, Soft Reboot the System);

static void freertosTaskList(void)
{
	char rtosRunStatus[512];

	Shell *shell = shellGetCurrent();
	shellPrint(shell, "-------------- FreeRTOS Run Status --------------\r\n");
	/*
	 * 'X' - Running
	 * 'B' – Blocked
	 * 'R' – Ready
	 * 'D' – Deleted (waiting clean up)
	 * 'S' – Suspended, or Blocked without a timeout
	 * Stack 为剩余的栈大小
	 */
	memset(rtosRunStatus, 0x00, sizeof(rtosRunStatus));
	vTaskList((char *)&rtosRunStatus);
    if (shell)
    {
        shellPrint(shell, "TaskName        Status  Prio    Stack   Index\r\n");
		shellPrint(shell, rtosRunStatus);
    }
	shellPrint(shell, "-------------------------------------------------\r\n");
	memset(rtosRunStatus, 0x00, sizeof(rtosRunStatus));
	vTaskGetRunTimeStats((char *)&rtosRunStatus);
    if (shell)
    {
        shellPrint(shell, "TaskName 	Runtime         CPU\r\n");
		shellPrint(shell, rtosRunStatus);
    }
	shellPrint(shell, "-------------------------------------------------\r\n");
	/* 此处展示的堆大小 已使用/总堆大小 [未分配的内存堆历史最小值] */
	shellPrint(shell, "Total Use HeapSize = %d/%d", (configTOTAL_HEAP_SIZE-xPortGetFreeHeapSize()),
			configTOTAL_HEAP_SIZE);

	/* xHACK 当内存分配方案不为heap_useNewlib_ST时选择这个如 heap4 */
	// shellPrint(shell, "Total Use HeapSize = %d/%d MiniFree[%d]", (configTOTAL_HEAP_SIZE-xPortGetFreeHeapSize()),
	// 		configTOTAL_HEAP_SIZE,
	// 		xPortGetMinimumEverFreeHeapSize());
}
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
top, freertosTaskList, List freeRTOS Task Status);


static void systemInfomationDisplay(void)
{
	char tempBuffer [32];
	char tempBuffer1[16];
	Shell *shell = shellGetCurrent();

	uint32_t osRunTicks = xTaskGetTickCount();
	uint32_t ss = 1000;
	uint32_t mm = ss * 60;
	uint32_t hh = mm * 60;
	uint32_t dd = hh * 24;
	uint32_t day  = osRunTicks / dd;
	uint32_t hour = (osRunTicks - day * dd) / hh;
	uint32_t minute  = (osRunTicks - day * dd - hour * hh) / mm;
	uint32_t second = (osRunTicks -day * dd - hour * hh - minute * mm) / ss;

    if (shell)
    {
		shellPrint(shell, "------------------------------------------------------------------------\r\n");
		shellPrint(shell, "Build:       " __DATE__ " " __TIME__ "\r\n");
        shellPrint(shell, "Author:      %s\r\n", DEVELOPER);
        shellPrint(shell, "Copyright:   (c) 2020 VThink Development Team\r\n");
		shellPrint(shell, "OSRunTime:   [%dDays-%dHours-%dMinutes-%dSeconds]\r\n", day, hour, minute, second);
		shellPrint(shell, "------------------------------------------------------------------------\r\n");
		shellPrint(shell, "MCU:         %s %s RAM/%s ROM CLK = %dMHz\r\n", MCU_TYPE, MCU_RAM, MCU_FLASH, SystemCoreClock/1000000);
		shellPrint(shell, "Internal:    VRef=%dmV/Temperature=%d°C/VBat=%dmV\r\n", readVref(), readTempSensor(), readButtonCell());
		shellPrint(shell, "H-Version:   %s\r\n", HARDWARE_VERSION);
		shellPrint(shell, "S-Version:   %s\r\n", SOFTWARE_VERSION);

//		shellPrint(shell, "millis() = %d, xTask = %d\r\n", millis(), xTaskGetTickCount());
	}
}
SHELL_EXPORT_CMD(
SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_DISABLE_RETURN,
xx, systemInfomationDisplay, Display system Information);
